package com.dingup.paike.util;

import com.dingup.api.Util.DateUtil;
import com.dingup.paike.bean.querybean.TimeInterval;
import com.dingup.paike.bean.utilbean.DateNode;
import com.dingup.paike.bean.utilbean.TeacherTimeNode;
import com.suyeer.basic.util.BasicUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.dingup.paike.util.ConstUtil.TIME_GO_TO_WORK;
import static com.dingup.paike.util.ConstUtil.TIME_OFF_DUTY;

/**
 * Created by wancheng on 2018/12/3.
 */
public class TeacherAvailableTimeUtil {

    private static final String DATE_FORMAT = "yyyy-MM-dd";
    private static final String HOUR_FORMAT = "HH:mm";
    private static final String PROCESS_UNIT_DAY = "DAY";
    private static final String PROCESS_UNIT_HOUR = "HOUR";

    public static List<TimeInterval> getAvailableTime(TimeInterval dayTime, List<TimeInterval> useTime, String userId) {
        List<TimeInterval> available = new ArrayList<>();
        if (useTime == null || CollectionUtils.isEmpty(useTime)) {
            TimeInterval availableTime = new TimeInterval();
            availableTime.setUserId(userId);
            availableTime.setHourBefore(DateUtil.getOnlyTimeFormatStr(dayTime.getBefore()));
            availableTime.setHourAfter(DateUtil.getOnlyTimeFormatStr(dayTime.getAfter()));
            availableTime.setBefore(dayTime.getBefore());
            availableTime.setAfter(dayTime.getAfter());
            available.add(availableTime);
            return available;
        }
        List<DateNode> dateNodes = new ArrayList<DateNode>();
        List<TeacherTimeNode> teacherTimeNodes = new ArrayList<>();
        //useTime.add(dayTime);
        useTime.forEach(
                t -> {
                    String uuid = BasicUtil.getUUID();
                    if (StringUtils.isBlank(t.getUserId())) {
                        uuid = "";
                    }
                    DateNode begin = new DateNode();
                    begin.setId(uuid);
                    begin.setIfBegin(true);
                    begin.setTime(t.getBefore());
                    DateNode end = new DateNode();
                    end.setId(uuid);
                    end.setIfBegin(false);
                    end.setTime(t.getAfter());
                    TeacherTimeNode teacherTimeNode = new TeacherTimeNode(uuid, begin, end);
                    teacherTimeNode.setUserId(userId);
                    dateNodes.add(begin);
                    dateNodes.add(end);
                    teacherTimeNodes.add(teacherTimeNode);
                }
        );

        Map<String, TeacherTimeNode> teacherTimeNodeMap = teacherTimeNodes.stream().collect(Collectors.toMap(TeacherTimeNode::getId, t -> t));


        List<DateNode> sort = dateNodes.stream().sorted((o1, o2) -> o1.getTime().compareTo(o2.getTime())).collect(Collectors.toList());
        for (int i = 0; i < sort.size(); i++) {
            DateNode current = sort.get(i);
            if (i != 0) {
                DateNode previous = sort.get(i - 1);
                previous.setHasNext(true);
                current.setPrevious(previous);
            }
            if (i != sort.size() - 1) {
                DateNode next = sort.get(i + 1);
                next.setHasPrevious(true);
                current.setNext(next);
            }
        }
        //记录并集的开始端
        DateNode begin = sort.get(0);
        //记录并集的结束端
        DateNode end = teacherTimeNodeMap.get(begin.getId()).getAfter();
        //指针作用
        DateNode hand = begin;
        while (hand != null) {
            //判断链表是否有前一个
            if (!hand.getHasPrevious()) {
                //没有上一位 说明是链表开头元素
                TimeInterval timeInterval = new TimeInterval();
                timeInterval.setBefore(dayTime.getBefore());
                timeInterval.setAfter(hand.getTime());
                timeInterval.setUserId(userId);
                available.add(timeInterval);
                hand = hand.getNext();
                continue;
            }
            if (!hand.getHasNext()) {
                //判断是否是最后一个
                TimeInterval timeInterval = new TimeInterval();
                timeInterval.setBefore(hand.getTime());
                timeInterval.setAfter(dayTime.getAfter());
                timeInterval.setUserId(userId);
                available.add(timeInterval);
                hand = hand.getNext();
                continue;
            }
            if (!hand.equals(end)) {
                hand = hand.getNext();
                if (hand.getIfBegin()) {
                    end = teacherTimeNodeMap.get(hand.getId()).getAfter();
                }
            } else {
                if (end.getHasNext()) {
                    TimeInterval timeInterval = new TimeInterval();
                    timeInterval.setBefore(end.getTime());
                    timeInterval.setAfter(end.getNext().getTime());
                    timeInterval.setUserId(userId);
                    available.add(timeInterval);

                    hand = end.getNext();
                    begin = hand;
                    end = teacherTimeNodeMap.get(begin.getId()).getAfter();
                }

            }

        }

        return available;
    }

    private static Date getDefaultDate(Date date, Boolean ifBefore) {
        String day = DateUtil.date2Str(date, DATE_FORMAT);
        String defaultTime = "";
        if (ifBefore) {
            defaultTime = day + " " + TIME_GO_TO_WORK;
        } else {
            defaultTime = day + " " + TIME_OFF_DUTY;
        }
        return DateUtil.str2Date(defaultTime);
    }

}
